package handle

import (
	"database/sql"
	"log"
	"os"
)

type SqlH struct{}

func (h *SqlH) Handle() (map[string]map[string]*string, error) {
	tab, err := h.GetTab(conf["dbname"])
	if err != nil {
		log.Fatal(err)
	}

	convH := &ConvH{}
	tar := make(map[string]map[string]*string)

	for _, v := range *tab {
		info := make(map[string]*string)
		info["$ENTITY$"] = convH.Hump(v)
		info["$TABLE$"] = &v

		cols, err := h.GetTabInfo(conf["dbname"], &v)
		if err != nil {
			log.Fatal(err)
		}
		info2, err := convH.sqlQuery(cols)
		if err != nil {
			log.Fatal(err)
		}
		for k1, v1 := range info2 {
			if k1 != "" {
				info[k1] = v1
			}
		}
		tar[v] = info
	}
	delete(tar, "")
	for k, v := range tar {
		log.Printf(" | %v | %v |", k, v)
		for k1, v1 := range v {
			log.Printf(" | %v | %v |", k1, *v1)
		}
	}
	return tar, nil
}

func (h *SqlH) GetTab(s *string) (*[]string, error) {
	query := "SELECT table_name " +
		"FROM information_schema.tables " +
		"WHERE table_schema=? " +
		"AND table_type='base table'"

	r, err := Conn.Query(query, s)
	defer func() {
		if err := r.Close(); err != nil {
			log.Printf("[ ERROR ] %v", err)
			os.Exit(1)
		}
	}()
	if err != nil {
		log.Fatal(err)
	}

	table := make([]string, 10, 10)
	for r.Next() {
		var tabName string
		err := r.Scan(&tabName)
		table = append(table, tabName)
		if err != nil {
			log.Fatal(err)
		}
	}
	return &table, nil
}

func (h *SqlH) GetTabInfo(db *string, tab *string) ([]map[string]string, error) {
	query := "SELECT column_name, data_type, column_key " +
		"FROM information_schema.columns " +
		"WHERE table_schema = ? " +
		"AND table_name = ?"

	r, err := Conn.Query(query, db, tab)
	defer func() {
		if err := r.Close(); err != nil {
			log.Printf("[ ERROR ] %v", err)
			os.Exit(1)
		}
	}()
	if err != nil {
		log.Printf("[ ERROR ] %v", err)
		return nil, err
	}

	columns, err := r.Columns()
	if err != nil {
		log.Printf("[ ERROR ] %v", err)
		return nil, err
	}

	values := make([]sql.RawBytes, len(columns))
	//定义一个切片,元素类型是interface{} 接口
	scanArgs := make([]interface{}, len(values))
	for i := range values {
		//把sql.RawBytes类型的地址存进去了
		scanArgs[i] = &values[i]
	}

	var cis []map[string]string
	for r.Next() {
		err = r.Scan(scanArgs...)
		if err != nil {
			log.Printf("[ ERROR ] %v", err)
			return nil, err
		}
		col := make(map[string]string)
		for i, v := range values {
			col[columns[i]] = string(v)
		}
		cis = append(cis, col)
	}

	//for _, v := range cis {
	//	log.Println(v)
	//	if v["column_key"] == "PRI" {
	//		log.Println("yes")
	//	}
	//}

	return cis, nil

}
